﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Acme.BookStore2.Permissions;
using Microsoft.AspNetCore.Authorization;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectExtending;

namespace Acme.BookStore2
{
    [Authorize(BookStore2Permissions.WorkSchedule.Default)]
    public class WorkScheduleAppService : ApplicationService, IWorkScheduleAppService
    {
        private readonly IWorkScheduleRepository _workScheduleRepository;
        private readonly WorkScheduleManager _workScheduleManager;

        public WorkScheduleAppService(IWorkScheduleRepository workScheduleRepository, WorkScheduleManager workScheduleManager)
        {
            _workScheduleRepository = workScheduleRepository;
            _workScheduleManager = workScheduleManager;
        }

        public async Task<WorkScheduleDto> GetAsync(Guid id)
        {
            return ObjectMapper.Map<WorkSchedule, WorkScheduleDto>(await _workScheduleRepository.GetAsync(id, false));
        }

        public async Task<PagedResultDto<WorkScheduleDto>> GetPagedListAsync(GetWorkSchedulesInput input)
        {
            var count = await _workScheduleRepository.GetCountAsync(input.CreationTimeBegin, input.CreationTimeEnd);
            var list = await _workScheduleRepository.GetPagedListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, input.CreationTimeBegin, input.CreationTimeEnd);
            return new PagedResultDto<WorkScheduleDto>(count, ObjectMapper.Map<List<WorkSchedule>, List<WorkScheduleDto>>(list));
        }

        [Authorize(BookStore2Permissions.WorkSchedule.Create)]
        public async Task<WorkScheduleDto> CreateAsync(WorkScheduleCreateDto input)
        {
            var workSchedule = new WorkSchedule(GuidGenerator.Create(), CurrentTenant.Id);

            UpdateWorkSchedule(workSchedule, input);
            input.MapExtraPropertiesTo(workSchedule);

            await _workScheduleRepository.InsertAsync(workSchedule);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<WorkSchedule, WorkScheduleDto>(workSchedule);
        }

        [Authorize(BookStore2Permissions.WorkSchedule.Update)]
        public async Task<WorkScheduleDto> UpdateAsync(Guid id, WorkScheduleUpdateDto input)
        {
            var workSchedule = await _workScheduleRepository.GetAsync(id);
            workSchedule.ConcurrencyStamp = input.ConcurrencyStamp;

            UpdateWorkSchedule(workSchedule, input);
            input.MapExtraPropertiesTo(workSchedule);

            await _workScheduleRepository.UpdateAsync(workSchedule);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<WorkSchedule, WorkScheduleDto>(workSchedule);
        }

        [Authorize(BookStore2Permissions.WorkSchedule.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            var workSchedule = await _workScheduleRepository.FindAsync(id);
            if (workSchedule == null)
            {
                return;
            }
            await _workScheduleRepository.DeleteAsync(workSchedule);
        }

        [Authorize(BookStore2Permissions.WorkSchedule.Export)]
        public async Task ExportAsync(GetWorkSchedulesInput input)
        {
        }
        
        private void UpdateWorkSchedule(WorkSchedule workSchedule, WorkScheduleCreateOrUpdateDtoBase input)
        {
            workSchedule.Title = input.Title;
            workSchedule.Description = input.Description;
            workSchedule.WorkType = input.WorkType;
            workSchedule.Remark = input.Remark;
        }
    }
}